# -*- coding: utf_8 -*-
# @Author : Administrator
# @Time : 2021/8/20
# @Remark: public_interface.py
import logging
from typing import List

from mxsoftpy import DB
from mxsoftpy.exception import ParamsError, DBError

from utils.conf.mxconfig import MxConfig
from index import _


class VideoConfDB(DB):
    def __init__(self, c_fk):
        """
        :param c_fk: 传过来的健名 --> str
        self.file : 数据库名
        self.main_key : 主键名
        self.path1 : 第一层目录
        self.sub_key : 拼接后的总路径
        """
        self.file = 'IOT'
        self.main_key = 'VideoQuality'
        self.path1 = 'Conf'
        self.sub_key = f'{self.path1}\\{c_fk}'

        super().__init__()

    def open_database(self, code: str = 0):
        """
        :param code: 设备项的code --> int
        打开当前数据库当前键的位址
        判断是否数据库存在此键
        """
        try:
            if code:
                return self.tree.open(self.main_key, f"{self.sub_key}\\{code}", file=self.file, host=MxConfig.HOST,
                                      port=MxConfig.PORT)
            else:
                return self.tree.open(self.main_key, self.sub_key, file=self.file, host=MxConfig.HOST,
                                      port=MxConfig.PORT)
        except DBError:
            logging.error("获取视频配置时，打开数据库失败，获取的配置类型：%s，配置键code：%s" % (self.sub_key, code))
            raise ParamsError(_('打开数据库失败'))

    def list(self, query_field: List[str]):
        """
        :param query_field: 要查询的字段 --> list
        返回所有数据
        data: 取到的所有的数据
        """
        data = self.open_database().sub_items(prop_list=query_field)
        return data if data else dict()

    def use_keys(self, query_field: List[str]) -> dict:
        """
        返回在用的数据
        :param query_field: 希望返回的字段
        """
        db = self.open_database()
        keys = db.filter(state=1)[1]
        data = db.sub_items(key_list=keys, prop_list=query_field) if keys else dict()

        return data

    def add(self, **kwargs):
        """
        kwargs: 数据字典，已校验
        增加一条数据
        conf_code: 增加配置成功后的id
        """
        conf_code = self.open_database().insert_key_items([(k, v) for k, v in kwargs.items()])
        logging.info('添加了一条数据，code为：%s' % conf_code)
        return conf_code

    def update(self, code: str, update_list: list):
        """
        修改一条数据
        :param code: 修改数据库的键名  --> int
        :param update_list: 修改的数据组 --> list
        update_res: 返回结果
        :return:
        """
        if update_list:
            try:
                update_res = self.open_database(code).insert_items(update_list, overwrite=True)
                logging.info('更新了一条数据，更新数据为：%s' % str(update_list))
                return update_res
            except DBError:
                raise ParamsError('修改数据失败')
        else:
            return ''

    def delete(self, code: str):
        """
        :param code: 修改数据库的键名  --> int
        删除一条数据
        delete_res: 返回结果·
        """
        try:
            delete_res = self.open_database(code).insert_item(prop='state', value=0, overwrite=True)
            logging.info('删除了一条数据，code为：%s' % code)
            return delete_res
        except DBError:
            raise ParamsError('删除数据失败')


class VideoDeviceDB(VideoConfDB):
    """设备类型"""
    pass


class StreamDB(VideoConfDB):
    """码流"""

    def retrieve(self, code: str) -> dict:
        """
        获取单个码流详情
        :param code: 要获取的码流code
        """
        return self.open_database(code).items()


class ResolutionDB(VideoConfDB):
    """分辨率"""
    pass


class TaskCycleDB(VideoConfDB):
    """任务周期"""
    pass


class TestItemsDB(VideoConfDB):
    """检测项目类型"""

    @staticmethod
    def __update_data(data: dict) -> dict:
        """
        补充字段
        """
        for i in data:
            if not data[i].get('max'):
                data[i]['min'] = 0
                data[i]['max'] = 0
                data[i]['reference'] = 0
                data[i]['step'] = 0
            else:
                data[i]['max'] = round(data[i]['max'], 2)
                data[i]['min'] = round(data[i]['min'], 2)
                data[i]['reference'] = round(data[i]['reference'], 3)
                data[i]['step'] = round(data[i]['step'], 3)
        return data

    def list(self, query_field: List[str]):
        """
        返回所有数据
        """
        try:
            data = self.open_database().sub_items(prop_list=query_field)
        except EOFError:
            raise ParamsError('查询数据失败')

        return self.__update_data(data) if data else dict()

    def use_keys(self, query_field: List[str]) -> dict:
        """
        返回在用的数据
        :param query_field: 希望返回的字段
        """
        db = self.open_database()
        keys = db.filter(state=1)[1]
        data = db.sub_items(key_list=keys, prop_list=query_field) if keys else dict()

        return self.__update_data(data)


def round_test_items(test_items: dict) -> dict:
    """
    处理测试项目浮点数
    """
    res_dict = {key: test_item for key, test_item in test_items.items()
                if not test_item.update({'confidence': round(test_item['confidence'], 3)})}

    return res_dict
